home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / TinyGL.lha / tinygl / src / glut.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-28  |  10.0 KB  |  404 lines

  1. // TODO: placer les prototypes dans glut.c
  2.     
  3. #include <stdio.h>
  4. //#include <lib/time.h>
  5.  
  6. #include <proto/intuition.h>
  7. #include <proto/graphics.h>
  8. #include <proto/exec.h>
  9.  
  10. #include <GL/glut.h>
  11. #include <GL/gla.h>
  12.  
  13. //#define __isMouseEvent(a) a >= EV_MOUSEEVENTS && a < EV_MOUSEEVENTS+6
  14. //#define __isKeyEvent(a) a >= EV_KEYBOARDEVENTS && a < EV_KEYBOARDEVENTS+3
  15.  
  16. #define SIGBREAKF_CTRL_C   (1<<12)
  17.  
  18. struct Library *CyberGfxBase;
  19.  
  20. typedef struct {
  21.     int x, y, width, height, depth;
  22.     struct Window *win;
  23.     GLboolean redisplay;
  24.     GLboolean reshape;
  25. } glut_window_t;
  26.  
  27. // Ajouter un __glut_state : quoique, il y a un windowCreated
  28. // ou __glut_initialized
  29.  
  30. //static glut_ave_t __glut_ave;
  31. static int __glut_initX = 0, __glut_initY = 0;
  32. static int __glut_initWidth = 320, __glut_initHeight = 256, __glut_initDepth = 8;
  33. static int __glut_mouseX = 0, __glut_mouseY = 0;
  34. static glut_window_t __glut_window;
  35. static GLAContext __glut_ctx = NULL;
  36. static int __glut_currWindow = 0;
  37. //static int __glut_numWindows = 0;
  38. static long __glut_initTime;
  39. static GLboolean __glut_fullScreen = GL_FALSE;
  40. static GLboolean __glut_windowCreated = GL_FALSE;
  41. //static char* __glut_windowName;
  42. static struct Screen *__glut_screen = NULL;
  43.  
  44. typedef void (*glut_displayFunc_t)();
  45. typedef void (*glut_idleFunc_t)();
  46. typedef void (*glut_keyboardFunc_t)(unsigned char key, int x, int y);
  47. typedef void (*glut_reshapeFunc_t)(int width, int height);
  48.  
  49. static glut_displayFunc_t __glut_displayFunc = NULL;
  50. static glut_idleFunc_t __glut_idleFunc = NULL;
  51. static glut_keyboardFunc_t __glut_keyboardFunc = NULL;
  52. static glut_reshapeFunc_t __glut_reshapeFunc = NULL;
  53.  
  54.  
  55. // Auxiliary functions
  56.  
  57. void __setupWindow() {
  58.     if (__glut_fullScreen) {
  59.         __glut_window.width = __glut_initWidth = glutGet(GLUT_SCREEN_WIDTH);
  60.         __glut_window.height = __glut_initHeight = glutGet(GLUT_SCREEN_HEIGHT);
  61.         __glut_window.x = __glut_window.y = 0;
  62.     }
  63.  
  64.     // Changer la position de la fenêtre
  65.  
  66.  
  67.     //glAMakeCurrent(__glut_window.win, __glut_ctx);
  68.     __glut_windowCreated = GL_TRUE;
  69. }
  70.  
  71.  
  72. // GLUT API Functions
  73.  
  74. void glutInit(int *argcp, char **argv) {
  75.     
  76.     CyberGfxBase = (struct Library *)OpenLibrary("cybergraphics.library", 41L);
  77.  
  78.     if (__glut_ctx != NULL) {
  79.     return;
  80.     }
  81.  
  82.     //__glut_initTime = microtime(NULL);
  83.     __glut_ctx = glACreateContext();
  84. }
  85.     
  86.  
  87. // TODO: Contrôler que ça ne sort pas de l'écran
  88. void glutInitWindowPosition(int x, int y) {
  89.     __glut_window.x = __glut_initX = x;
  90.     __glut_window.y = __glut_initY = y;
  91. }
  92.  
  93.  
  94. // TODO: S'assurer que la largeur soit multiple de 4 (ou 8 ?)
  95. void glutInitWindowSize(int width, int height) {
  96.     __glut_window.width = __glut_initWidth = width;
  97.     __glut_window.height = __glut_initHeight = height;
  98. }
  99.  
  100.  
  101. // renseigner __glut_window.depth = GetBitMapAttr(window->BitMap, BMA_DEPTH);
  102. int glutCreateWindow(char *name) {
  103.     struct Screen *screen = NULL;
  104.     unsigned long modeID = INVALID_ID;
  105.                                                         
  106.     /* Récupérer la profondeur de l'écran Workbench */
  107.  
  108.     
  109.  
  110.  
  111.     /* Mode d'écran */
  112.     if (CyberGfxBase)
  113.   {
  114.         modeID = BestCModeIDTags(CYBRBIDTG_Depth, __glut_initDepth,
  115.                                                             CYBRBIDTG_NominalWidth, __glut_initWidth,
  116.                                                             CYBRBIDTG_NominalHeight, __glut_initHeight,
  117.                                                             TAG_DONE);
  118.     /*
  119.         screen = LockPubScreen(NULL);
  120.         if (screen != NULL){
  121.             // Open the window on the current screen
  122.  
  123.  
  124.             UnlockPubScreen(NULL, screen);
  125.         }
  126.     }else{
  127.         // Ouverture d'un écran et d'une fenêtre
  128.         
  129.  
  130.     */
  131.     }
  132.    
  133.     if (modeID == (unsigned long)INVALID_ID){
  134.         modeID = BestModeID(
  135.                 BIDTAG_NominalWidth, __glut_initWidth,
  136.                 BIDTAG_NominalHeight, __glut_initHeight,
  137.                 BIDTAG_Depth, __glut_initDepth,
  138.         BIDTAG_MonitorID, DBLPAL_MONITOR_ID,
  139.         TAG_END);
  140.     }
  141.  
  142.     if (modeID == (unsigned long)INVALID_ID){
  143.         return 0;
  144.   }
  145.  
  146.     screen = OpenScreenTags(NULL,
  147.                                      SA_Width, __glut_initWidth,
  148.                                      SA_Height, __glut_initHeight,
  149.                                      SA_Depth, __glut_initDepth,
  150.                                      SA_Title, (ULONG)"TinyGL",
  151.                                      SA_ShowTitle, FALSE,
  152.                                      SA_Type, CUSTOMSCREEN,
  153.                                      SA_SharePens, TRUE,
  154.                                      SA_DisplayID, modeID,
  155.                                      SA_Interleaved, TRUE,
  156.                                      SA_FullPalette, TRUE,
  157.                                      TAG_DONE);
  158.     
  159.   __glut_screen = screen;
  160.  
  161.     __glut_window.win = OpenWindowTags(NULL,
  162.                         WA_Left, __glut_initX,
  163.                         WA_Top, __glut_initY,
  164.                         WA_Width, __glut_initWidth,
  165.                         WA_Height, __glut_initHeight,
  166.                         WA_CustomScreen, (ULONG)screen,
  167.                         WA_SizeGadget, FALSE,
  168.                         WA_CloseGadget, FALSE,
  169.                         WA_RMBTrap, TRUE,
  170.             //WA_CloseGadget, TRUE,
  171.             //WA_DepthGadget, TRUE,
  172.             WA_Activate, TRUE,
  173.                         WA_Title, (unsigned long)name,
  174.                         WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_ACTIVEWINDOW| IDCMP_IDCMPUPDATE | IDCMP_CHANGEWINDOW | IDCMP_NEWSIZE | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_VANILLAKEY | IDCMP_RAWKEY, // | IDCMP_INTUITICKS | IDCMP_NEWSIZE,
  175.             WA_Flags, WFLG_SIZEGADGET | WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET, // | WFLG_REPORTMOUSE,
  176.             TAG_END);
  177.                 
  178.     __glut_window.depth = GetBitMapAttr(__glut_window.win->RPort->BitMap, BMA_DEPTH);
  179.         
  180.     glAMakeCurrent(__glut_window.win, __glut_ctx);
  181.  
  182.   __glut_window.redisplay = GL_TRUE;
  183.     __glut_window.reshape = GL_TRUE;
  184.  
  185.  
  186.     return 1;
  187. }
  188.  
  189.  
  190. void glutSwapBuffers(void) {
  191.     glASwapBuffers(__glut_window.win);
  192. }
  193.  
  194.  
  195. void glutFullScreen(void) {
  196.     __glut_fullScreen = GL_TRUE;
  197.     __setupWindow();
  198. }
  199.  
  200.  
  201. void glutSetWindow(int win) {
  202.     __glut_currWindow = win;
  203. }
  204.  
  205.  
  206. int glutGetWindow(void) {
  207.     return __glut_currWindow;
  208. }
  209.  
  210.  
  211. void glutDestroyWindow(int win) {
  212.     glADestroyContext(__glut_ctx);
  213.     CloseWindow(__glut_window.win);
  214.     __glut_window.win = NULL;
  215.     __glut_windowCreated = GL_FALSE;
  216.  
  217.     // TODO: Close the screen only if it's a private one
  218.     CloseScreen(__glut_screen);
  219.     __glut_screen = NULL;
  220. }
  221.  
  222.  
  223. // Afficher la fenêtre si
  224. //            __glut_displayFunc();
  225. //            __glut_window.redisplay = GL_FALSE;
  226. // TODO: passer les coordonnées du pointeur souris à keyboard()
  227. void glutMainLoop(void) {
  228.     struct Window *WinHandle = NULL;
  229.     int done = 0;
  230.     ULONG portsig, waitsigs;
  231.     struct IntuiMessage *imsg = NULL;
  232.  
  233.   if (!__glut_windowCreated) {
  234.         __setupWindow();
  235.     }
  236.  
  237.     if ((__glut_window.reshape) && (__glut_reshapeFunc != NULL)){
  238.         __glut_reshapeFunc(__glut_window.width, __glut_window.height);
  239.         __glut_window.reshape = GL_FALSE;
  240.     }
  241.                                                                 
  242.     WinHandle = __glut_window.win;
  243.  
  244.         //WaitPort(MyWindow->UserPort);
  245.         //MyWinMsg = (struct IntuiMessage *) GetMsg(MyWindow->UserPort);
  246.  
  247.     portsig = 1L << WinHandle->UserPort->mp_SigBit;
  248.         while (done == 0){
  249.  
  250.       waitsigs = Wait(portsig | SIGBREAKF_CTRL_C);
  251.       if (waitsigs & portsig){
  252.         while (imsg = (struct IntuiMessage *)GetMsg(WinHandle->UserPort)){
  253.              
  254.           switch (imsg->Class){
  255.             case IDCMP_CLOSEWINDOW:
  256.               done = 1;
  257.               break;
  258.             case IDCMP_IDCMPUPDATE:
  259.                             //printf("IDCMPUPDATE\n");
  260.               break;
  261.             case IDCMP_VANILLAKEY:
  262.                             // TODO: passer les coordonnées à la place de (0,0)
  263.                             //printf("Code VANILLAKEY = %d\n", imsg->Code);
  264.               if (imsg->Code == 27){
  265.                                 done = 1;
  266.               }else{
  267.                                 if (__glut_keyboardFunc){
  268.                                     __glut_keyboardFunc(imsg->Code, 0, 0);
  269.                                 }
  270.               }
  271.               break;
  272.             case IDCMP_NEWSIZE:
  273.                             //printf("NEWSIZE\n");
  274.               break;
  275.             case IDCMP_MOUSEMOVE:
  276.                             //__glut_mouseX = ave_event.msg->EVD_X;
  277.                             //__glut_mouseY = ave_event.msg->EVD_Y;
  278.                             //printf("MOUSEMOVE\n");
  279.               break;
  280.             case IDCMP_CHANGEWINDOW:
  281.                             //printf("CHANGEWINDOW\n");
  282.               break;
  283.             case IDCMP_REFRESHWINDOW:
  284.                             //printf("REFRESHWINDOW\n");
  285.               break;
  286.             case IDCMP_ACTIVEWINDOW:
  287.                             //printf("ACTIVEWINDOW\n");
  288.               break;
  289.                         case IDCMP_MOUSEBUTTONS:
  290.                             //case IECODE_LBUTTON:
  291.     
  292.                             break;
  293.             case IDCMP_RAWKEY:
  294.                             // Code 45 : escape
  295.                             //printf("RAWKEY\n");
  296.                             //printf("Code RAWKEY = %d\n", imsg->Code);
  297.                             if (__glut_keyboardFunc != NULL) {
  298.                                 __glut_keyboardFunc(imsg->Code, 0, 0);
  299.                             }
  300.               break;
  301.                         //default:
  302.                             //printf("IDCMP_default\n");
  303.           }
  304.                     ReplyMsg((struct Message *)imsg);
  305.         }
  306.       }
  307.       if (waitsigs & SIGBREAKF_CTRL_C){
  308.         done = 1;
  309.       }
  310.  
  311.  
  312.         // Comme pour keyboardFunc, vérifier aussi que displayFunc n'est pas NULL
  313.         // Idem pour reshapeFunc
  314.  
  315.         if ((__glut_window.redisplay) && (__glut_displayFunc != NULL)){
  316.             __glut_displayFunc();
  317.             __glut_window.redisplay = GL_FALSE;
  318.         }
  319.         if ((__glut_window.reshape) && (__glut_reshapeFunc != NULL)){
  320.             __glut_reshapeFunc(__glut_window.width, __glut_window.height);
  321.             __glut_window.reshape = GL_FALSE;
  322.         }
  323.         if (__glut_idleFunc != NULL) {
  324.             __glut_idleFunc();
  325.         }
  326.  
  327.         }
  328.      
  329.     glutDestroyWindow(0);
  330.  
  331.     CloseLibrary(CyberGfxBase);
  332. }
  333.  
  334.  
  335. void glutPostRedisplay(void) {
  336.     __glut_window.redisplay = GL_TRUE;
  337. }
  338.  
  339.  
  340. void glutDisplayFunc(void (*func)(void)) {
  341.     __glut_displayFunc = func;
  342. }
  343.  
  344.  
  345. void glutReshapeFunc(void (*func)(int width, int height)) {
  346.     __glut_reshapeFunc = func;
  347. }
  348.  
  349.  
  350. void glutIdleFunc(void (*func)(void)) {
  351.     __glut_idleFunc = func;
  352. }
  353.  
  354.  
  355. void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) {
  356.     __glut_keyboardFunc = func;
  357. }
  358.  
  359. // TODO : gérer ELAPSED_TIME
  360. // TODO : remettre les screen height et width
  361. int glutGet(GLenum state) {
  362.  
  363.     switch (state) {
  364.     case GLUT_WINDOW_X :
  365.         return __glut_window.x;
  366.     case GLUT_WINDOW_Y :
  367.         return __glut_window.y;
  368.     case GLUT_WINDOW_WIDTH :
  369.         return __glut_window.width;
  370.     case GLUT_WINDOW_HEIGHT :
  371.         return __glut_window.height;
  372.     case GLUT_WINDOW_DEPTH_SIZE :
  373.         return __glut_window.depth;
  374.     case GLUT_WINDOW_PARENT :
  375.         return 0;
  376.     case GLUT_WINDOW_NUM_CHILDREN :
  377.         return 0;
  378.     case GLUT_SCREEN_WIDTH :
  379.         return __glut_window.win->WScreen->Width;
  380.     case GLUT_SCREEN_HEIGHT :
  381.         return __glut_window.win->WScreen->Height;
  382.     case GLUT_SCREEN_WIDTH_MM :
  383.         return 0;
  384.     case GLUT_SCREEN_HEIGHT_MM :
  385.         return 0;
  386.     case GLUT_INIT_WINDOW_X :
  387.         return __glut_initX;
  388.     case GLUT_INIT_WINDOW_Y :
  389.         return __glut_initY;
  390.     case GLUT_INIT_WINDOW_WIDTH :
  391.         return __glut_initWidth;
  392.     case GLUT_INIT_WINDOW_HEIGHT :
  393.         return __glut_initHeight;
  394.     case GLUT_ELAPSED_TIME :
  395.         return 0; //(int) ((microtime(NULL) - __glut_initTime)/1000);
  396.     }
  397.  
  398.     return -1;
  399. }
  400.  
  401. /// Not implemented
  402. void glutInitDisplayMode(unsigned int mode) {}
  403.  
  404.